import { ref } from 'vue'
import SparkMD5 from 'spark-md5'
import api from '@/api/axios.js'
import { ElMessage } from 'element-plus'

export function useUploadFile() {
  const needs = ref([])
  const splitedFile = ref({})
  const showProgress = ref(false)
  const progressPercent = ref(0)
  const showButton = ref(false)
  const btnText = ref('上传')
  const buttonStatus = ref('unchoose')
  const hooks = ref({})

  /**
   * 设置进度条区域
   */
  const setProgress = () => {
    const total = splitedFile.value.chunkInfos.length
    let percent = ((total - needs.value.length) / total) * 100
    percent = Math.ceil(percent)
    showProgress.value = true
    progressPercent.value = percent
  }

  /**
   * 设置上传按钮状态
   */
  const setStatus = () => {
    const status = buttonStatus.value
    switch (status) {
      case 'unchoose': // 未选择文件
        showButton.value = false
        break;
      case 'choose': // 刚刚选择了文件
        showButton.value = true
        btnText.value = '上传'
        break;
      case 'uploading': // 上传中
        showButton.value = true
        btnText.value = '暂停'
        break;
      case 'pause': // 暂停中
        showButton.value = true
        btnText.value = '继续'
        break;
      case 'finish': // 已完成
        showButton.value = false
        btnText.value = '完成'
        break;
    }
  }
  /**
   * 对文件进行分片
   * @param {file} 文件
   */
  const splitFile = (file) => {
    return new Promise((resolve, reject) => {
      let chunkSize = 1024 * 1024 //1MB
      let chunkCount = Math.ceil(file.size / chunkSize)
      let chunkIndex = 0
      //分片信息数组
      let chunkInfos = []
      let fileReader = new FileReader()
      // 使用ArrayBuffer完成文件MD5编码
      let spark = new SparkMD5.ArrayBuffer()
      fileReader.onload = (e) => {
        spark.append(e.target.result)
        // 当前分片单独的MD5，chunkIndex可防止分片hash内容重复
        let chunkMD5 = SparkMD5.ArrayBuffer.hash(e.target.result) + chunkIndex
        // Blob构造函数接受两个参数：一个是包含数据的数组，另一个是可选的包含两个属性的对象，分别是type和endings
        chunkInfos.push({
          id: chunkMD5,
          content: new Blob([e.target.result])
        })
        chunkIndex++
        if (chunkIndex >= chunkCount) resolve({
          fileID: spark.end(),
          ext: extname(file.name),
          chunkInfos
        })
        else loadNextChunk()
      }
      function loadNextChunk() {
        let start = chunkIndex * chunkSize
        let temp = start + chunkSize
        let end = temp > file.size ? file.size : temp
        fileReader.readAsArrayBuffer(file.slice(start, end))
      }
      //读取文件后缀名
      function extname(filename) {
        let i = filename.lastIndexOf('.')
        if (i < 0) { return '' }
        return filename.substring(i)
      }
      loadNextChunk()

    })
  }
  /**
   * 处理上传按钮点击事件
   */
  const handleBtnChange = () => {
    switch (buttonStatus.value) {
      case 'unchoose':
      case 'finish':
        return;
      case 'uploading':
        buttonStatus.value = 'pause';
        setStatus();
        break;
      case 'choose':
      case 'pause':
        buttonStatus.value = 'uploading';
        uploadPiece();
        setStatus();
        break;
    }
  }
  /**
   * 对分片进行上传
   */
  const uploadPiece = async () => {
    if (!needs.value) {
      // this.$message.open({
      //   tittle: '请选择需要上传的文件！',
      //   type: 'info',
      //   duration: 1000,
      //   center: true
      // })
      return
    }
    if (needs.value.length === 0) {
      // 上传完成
      setProgress()
      buttonStatus.value = 'finish'
      setStatus()
      if (hooks.value.handleFinish && typeof hooks.value.handleFinish === 'function') {
        hooks.value.handleFinish()
      }
      ElMessage.success('视频文件上传完成！')
      return
    }
    if (buttonStatus.value !== 'uploading') {
      return;
    }
    const nextChunkId = needs.value[0]
    const file = splitedFile.value.chunkInfos.find((it) => it.id === nextChunkId).content
    const formData = new FormData()
    formData.append('file', file)
    formData.append('chunkId', nextChunkId)
    formData.append('fileId', splitedFile.value.fileID)
    formData.append('ext', splitedFile.value.ext)
    const res = await api.uploadFilePiece(formData)
    needs.value = res.data.data
    setProgress()
    uploadPiece()
  }

  // 将 Blob URL 转换为 File 对象
  const blobURLtoFile = async (blobURL, filename) => {
    try {
      const response = await fetch(blobURL)
      const blob = await response.blob()
      return new File([blob], filename, { type: blob.type })
    } catch (error) {
      console.error('Error converting blob URL to file:', error)
      throw error
    }
  }

  // 上传封面
  const uploadCover = async (coverImg, params) => {
    if (coverImg) {
      try {
        const coverFile = await blobURLtoFile(coverImg, splitedFile.value.fileID)
        const response = await api.uploadFile(coverFile, params)
        console.log('response', response)
      } catch (error) {
        console.log('error：文件上传出错！')
      }
    } else return
  }

  return {
    hooks,
    needs,
    buttonStatus,
    btnText,
    splitedFile,
    progressPercent,
    showButton,
    setProgress,
    setStatus,
    splitFile,
    handleBtnChange,
    uploadPiece,
    uploadCover,
    blobURLtoFile
  }
}